package com.graduation.sfstore.server;

import com.graduation.sfstore.dao.TemperatureMapper;
import com.graduation.sfstore.entity.Event;
import com.graduation.sfstore.entity.TemperatureData;
import com.graduation.sfstore.event.EventProducer;
import com.graduation.sfstore.service.TemperatureService;
import com.graduation.sfstore.util.SFWarehouseConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Set;


/**
 * nio socket服务端
 */
@Service
public class SocketServer {

    @Autowired
    private EventProducer eventProducer;

    @Resource
    private TemperatureMapper temperatureMapper;


    // 解码buffer
    private Charset cs = Charset.forName("UTF-8");

    // 接受数据缓冲区
    private static ByteBuffer sBuffer = ByteBuffer.allocate(1024);

    // 发送数据缓冲区
    private static ByteBuffer rBuffer = ByteBuffer.allocate(1024);

    // 选择器
    private static Selector selector;


    /**
     * 启动socket服务，开启监听
     *
     * @param port
     */
    public void startSocketServer(int port) {
        try {
            // 打开通信通道
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            // 设置为非阻塞
            serverSocketChannel.configureBlocking(false);
            // 获取套接字
            ServerSocket serverSocket = serverSocketChannel.socket();
            // 绑定端口号
            serverSocket.bind(new InetSocketAddress(port));
            // 打开监听
            selector = Selector.open();
            // 将通信信道注册到监听器
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            // 监听器一直监听，如果客户端有请求就会进入响应的时间处理
            while (true) {
                selector.select(); // select()一直阻塞直到相关事件发生或超时
                Set<SelectionKey> selectionKeys = selector.selectedKeys(); // 监听到事件
                for (SelectionKey key : selectionKeys) {
                    handle(key);
                }
                selectionKeys.clear(); // 清除处理过的事件
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理不同事件
     *
     * @param selectionKey
     * @throws IOException
     */
    private void handle(SelectionKey selectionKey) throws IOException {
        ServerSocketChannel serverSocketChannel = null;
        SocketChannel socketChannel = null;
        String requestMsg = "";
        int count = 0;
        if (selectionKey.isAcceptable()) {
            // 每有客户端连接，即注册通信信道为可读
            serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
            socketChannel = serverSocketChannel.accept();
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);
            System.out.println("客户端连接成功");
        } else if (selectionKey.isReadable()) {
            socketChannel = (SocketChannel) selectionKey.channel();
            rBuffer.clear();
            count = socketChannel.read(rBuffer);
            // 读取数据
            if (count > 0) {
                rBuffer.flip();
                requestMsg = String.valueOf(cs.decode(rBuffer).array());
                String responseMsg = "客户端消息：" + requestMsg;
                String material = requestMsg;


//                TemperatureData temperatureData = new TemperatureData();
//                String temperature = material.substring(1,3);
//                System.out.println(temperature);
//                String humidity = material.substring(3,5);
//                System.out.println(humidity);
//
//                temperatureData.setTemperature(temperature);
//                temperatureData.setHumidity(humidity);
//                temperatureData.setMaterial(material);
//                int i = temperatureMapper.insertTemperature(temperatureData);


                System.out.println(material);


//                Event event = new Event()
//                        .setTopic("receive")
//                        .setFishname(material);
//                System.out.println(event);
//
//                eventProducer.fireEvent(event);


                System.out.println(responseMsg);

            }
            // 返回数据
//			sBuffer = ByteBuffer.allocate(responseMsg.getBytes().length);
//			sBuffer.put(responseMsg.getBytes());
//			sBuffer.flip();
//			socketChannel.write(sBuffer);
//			socketChannel.close();
        }
    }

}


